 /**
     * 下单
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional
    public ResponseResult downOrder(OrderDto orderDto) {

        // 创建锁对象
        RLock redisLock = redissonClient.getLock(RedisConstants.ORDER_LOCK_KEY+ AppThreadLocalUtil.getUser().getId());
        // 尝试获取锁
        boolean isLock = redisLock.tryLock();
        // 判断
        if (!isLock) {
            // 获取锁失败，直接返回失败或者重试
            return ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_INVALID,"订单服务繁忙 请稍后再试");
        }

        Order order = null;

        try {
            //1.检查参数
            if (orderDto == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"下单参数为空");
            }

            //2.1 查询商品是否存在
            ResponseResult responseResult = goodsClient.ProductById(orderDto.getGoodsId());
            if (responseResult.getCode()!=200){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"远程调用获取商品数据失败");
            }

            //拿取商品信息
            String jsonString = JSONUtil.toJsonStr(responseResult.getData());
            Product product = JSONUtil.toBean(jsonString, Product.class);

            // 检查商品状态是否可购买
            if (product.getStatus() != STATUS_UP) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "商品已下架或不可购买");
            }



            //获取购买者id
            Integer userId = AppThreadLocalUtil.getUser().getId();
            if (userId == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_INVALID,"获取购买者用户id失败");
            }

            //2.查询是否重复购买
            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Order::getGoodsId, orderDto.getGoodsId())
                    .eq(Order::getSenderId, userId)
                    .ne(Order::getStatus, OrderStatus.CANCELLED_CLOSED); // 状态等于5才可以购买

            //使用 ne 方法添加一个“不等于”的条件，排除状态为5（CANCELLED_CLOSED）的订单。
            //这样，查询结果中只会包含状态不为5的订单。

            Order OrderCheck = orderMapper.selectOne(queryWrapper);
            if (OrderCheck != null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"您已经购买过该商品了");
            }


            //2.生成全局唯一订单号
            long orderId = redisTimeWorker.nextID("order");








            //生成订单
            order = new Order();
            order.setId(orderId);
            order.setPaymentType(orderDto.getPaymentType());
            order.setStatus(OrderStatus.UNPAID);
            order.setTotalFee(orderDto.getTotalFee());
            order.setGoodsId(orderDto.getGoodsId());
            //设置购买者id
            order.setSenderId(Long.valueOf(userId));
            //设置卖家id
            order.setReceiverId(orderDto.getSellerId());
            order.setCreateTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());




            //4.订单入库
            int insert = orderMapper.insert(order);
            if (insert<=0){
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"订单入库失败");
            }


            // 5.更新商品状态
            ProductDto productDto=new ProductDto();

            productDto.setId(product.getId());
            productDto.setStatus(0);
            productDto.setUserId(orderDto.getSellerId());


            //远程调用商品下架
            ResponseResult responseResult1 = goodsClient.updateStatus(productDto);


            if (responseResult1.getCode()!=200){
                throw new RuntimeException("远程调用商品下架失败");
            }


            //生成订单详情信息
            OrderDetail orderDetail =new OrderDetail();
            orderDetail.setGoodsId(product.getId());
            orderDetail.setOrderId(orderId);
            orderDetail.setNum(1);
            orderDetail.setImage(product.getImages());
            orderDetail.setName(product.getTitle());
            orderDetail.setRemark(orderDto.getRemark());
            orderDetail.setPrice(product.getPrice());



            //5.异步生成订单详情信息
            createOrderDetil(orderDetail);


            //向前端发回订单号
            return ResponseResult.okResult(order.getId().toString());

        } catch (AmqpException e) {
            throw new RuntimeException(e);
        } finally {
            //判断是当前线程持有锁 才能释放锁
            if (redisLock.isHeldByCurrentThread()) {
                redisLock.unlock();
            }
        }


    }

    //异步生成订单详情
    @Async("twotwoExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void createOrderDetil(OrderDetail orderDetail) {

        if (orderDetail==null){
            throw new RuntimeException("订单详情信息入库失败");
        }

        orderDetail.setCreateTime(LocalDateTime.now());
        orderDetail.setUpdateTime(LocalDateTime.now());

        orderDetailMapper.insert(orderDetail);

    }
